﻿// Inner Kit 库
// 通用工具类
// Copyright (c) 2023 by 尔西大帝. All rights reserved.
//
// 这个文件包括一些常量与宏的定义。以及所有项目都要用到的最基础的工具。
//
// Author: 尔西大帝
// Email: 2670613871@qq.com
// Created: 2024-11-14

#pragma once

#include <cstdint>
#include <string.h>
#include <string>

// 快捷操作

#define SAFE_DELETE(o)                                                         \
  if (o) {                                                                     \
    delete o;                                                                  \
    o = nullptr;                                                               \
  }
#define SAFE_DELETE_ARRAY(o)                                                   \
  if (o) {                                                                     \
    delete[] o;                                                                \
    o = nullptr;                                                               \
  }
#define SAFE_FREE(o)                                                           \
  if (o) {                                                                     \
    free(o);                                                                   \
    o = nullptr;                                                               \
  }

namespace ikit {
/*
 * 基本输入输出流
 */
// 读取一个文件
std::string read_txt_file(const char* filename);
// 读取日志文件
std::string get_log();
// 获得当前的工作目录
std::string get_current_dir();

/*
 * 日志功能
 */
// 设置输出流为文件
// is_append = 是否追加。如果为False，会清空原来的文件
void set_log_output_file(const char* filename, bool is_append);
// 输出到输出流
void print(const char* format, ...);
// 输出到输出流，和kprint唯一的不同就是会在后面增加回车换行。
void log(const char* format, ...);
// 输出错误到输出流
void error(const char* format, ...);
// 对行尾进行变换，将\n换成\r\n（这个在EditText中才能换行）。
std::string replace_with_CrLf(const std::string& input);

/*
 * 字符串功能
 */
// 比较字符串，不区别大小写。返回true为一样，false为不一样。没有比大小的功能。
inline bool str_equal(const char* s1, const char* s2) {
  return _stricmp(s1, s2) == 0;
}
// 复制一个字符串（会重新分配内存）
char* str_copy(const char* str);
// 将utf-8的字符串转为GBK（这东西被C++17弃用了）
std::string utf8_to_gbk(const std::string& utf8_str);

/*
 * 数字功能
 */
// 判断一个字符串是否是整数
bool is_number(const char* s);
// 判断一个字符串是否是符点数
bool is_float(const char* s);
// 判断一个字符串是否是二进制数
bool is_hex(const char* s);
// 将一个16进制字符转为数字
int hex_to_number(char c);
// 将一个16进制字符转为UINT
uint32_t hex_to_uint(const char* buf);
// 得到一个Hash值
uint32_t hash(const char* str);
uint64_t hash64(const char* str);

/*
 * 数学功能
 * 因为这和一些库冲突，所以改为了大写。本来应该全小写的
 */
// Returns random float in [0, 1).
static float Rand() { return (float)(rand()) / (float)RAND_MAX; }
// Returns random float in [a, b).
static float Randf(float a, float b) { return a + Rand() * (b - a); }
static int Rand(int a, int b) { return a + rand() % ((b - a) + 1); }
template <typename T> static T Min(const T& a, const T& b) {
  return a < b ? a : b;
}
template <typename T> static T Max(const T& a, const T& b) {
  return a > b ? a : b;
}
template <typename T> static T Lerp(const T& a, const T& b, float t) {
  return a + (b - a) * t;
}
template <typename T> static T Clamp(const T& x, const T& low, const T& high) {
  return x < low ? low : (x > high ? high : x);
}

} // namespace ikit

#if defined(DEBUG) || defined(_DEBUG)
#define KLOG ikit::log
#define KERROR ikit::error
#define KPRINT ikit::print
#else
#define KLOG
#define KERROR
#define KPRINT
#endif
